home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume17 / calentool / part02 < prev    next >
Encoding:
Internet Message Format  |  1991-04-04  |  54.8 KB

  1. From: billr@saab.CNA.TEK.COM (Bill Randle)
  2. Newsgroups: comp.sources.misc
  3. Subject: v17i083:  calentool - day/week/month/year-at-a-glance SunView tool, Part02/23
  4. Message-ID: <1991Apr4.052012.5641@sparky.IMD.Sterling.COM>
  5. Date: 4 Apr 91 05:20:12 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: 131b55e9 a6faa4b7 9e1dee53 879ea81c
  8.  
  9. Submitted-by: Bill Randle <billr@saab.CNA.TEK.COM>
  10. Posting-number: Volume 17, Issue 83
  11. Archive-name: calentool/part02
  12.  
  13. #! /bin/sh
  14. # This is a shell archive.  Remove anything before this line, then unpack
  15. # it by saving it into a file and typing "sh file".  To overwrite existing
  16. # files, type "sh file -c".  You can also feed this as standard input via
  17. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  18. # will see the following message at the end:
  19. #        "End of archive 2 (of 23)."
  20. # Contents:  Fixes1_3 Patches2_1 datelib.c
  21. # Wrapped by billr@saab on Thu Mar 28 08:38:11 1991
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f 'Fixes1_3' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'Fixes1_3'\"
  25. else
  26. echo shar: Extracting \"'Fixes1_3'\" \(228 characters\)
  27. sed "s/^X//" >'Fixes1_3' <<'END_OF_FILE'
  28. X# $Header: Fixes1_3,v 1.1 88/04/08 11:27:57 billr Exp $
  29. X
  30. XVersion 1.3 update:
  31. X
  32. X1) Add code to handle command line arguments (mainly because I
  33. X   like it to come up iconic and put the icon where I want it).
  34. X
  35. X    -Bill Randle
  36. X    2/3/88
  37. END_OF_FILE
  38. if test 228 -ne `wc -c <'Fixes1_3'`; then
  39.     echo shar: \"'Fixes1_3'\" unpacked with wrong size!
  40. fi
  41. # end of 'Fixes1_3'
  42. fi
  43. if test -f 'Patches2_1' -a "${1}" != "-c" ; then 
  44.   echo shar: Will not clobber existing file \"'Patches2_1'\"
  45. else
  46. echo shar: Extracting \"'Patches2_1'\" \(6274 characters\)
  47. sed "s/^X//" >'Patches2_1' <<'END_OF_FILE'
  48. X# $Header: Patches2_1,v 2.7 90/01/04 15:08:48 billr Exp $
  49. X
  50. X#$Log:    Patches2_1,v $
  51. X# Revision 2.7  90/01/04  15:08:48  billr
  52. X# Patchlevel 6 of calentool fixes the following bugs:
  53. X# 
  54. X#===========
  55. X#Bugs Fixed:
  56. X#===========
  57. X#Fix bug where holidays are not shown in the day display if there
  58. X#    are no regular appointments for that day. <smb@research.att.com>,
  59. X#    <phil@grumpy.cgrg.ohio-state.edu>
  60. X#Fix bug that caused the year display to be off by one on its display.
  61. X#    <seamans@seaimage@nlm.nih.gov>, <shen@burma.crd.ge.COM>
  62. X#Fixed typos in the world and space date files. <rodgers@maxwell.mmwb.ucsf.edu>
  63. X#Added a warning to the Makefile regarding optimizing the "wpaint.c" file.
  64. X#    <seamans@seaimage@nlm.nih.gov>
  65. X#
  66. X# Revision 2.6  89/12/15  17:13:23  billr
  67. X# Patchlevel 5 of calentool fixes the following bugs and adds features:
  68. X# 
  69. X# ===========
  70. X# Bugs Fixed:
  71. X# ===========
  72. X# calentool -p -m misses warnings in advance if the warning and 
  73. X#     appointments are in different month.  <kayhan@eve.usc.edu>
  74. X# Fixed bug with day/week PostScript printouts [reported by several people]
  75. X# Fixed bug with "-m" option [reported by several people]
  76. X# Corrected date for Australia Day <ajc@philabs.philips.COM>
  77. X# Fixed -p/-P/-m options so nothing is printed (or mailed) if there are
  78. X#     no appointments for the day. <uunet.uu.net!xlab!milt!milt>, <brooks@ge-dab.crd.ge.COM>
  79. X# Fixed bug whereby entire calentool was being changed to black&white
  80. X#     after the Moon data frame was displayed.
  81. X# Fixed bug in calculation of Jewish passover (on which all the other
  82. X#     Jewish holidays are based) <smb@hector.att.COM>, <rjc@cs.brown.edu>
  83. X# Fixed bug that displayed previous days calendar if a day is selected from a 6 day week. <bob@omni.COM>
  84. X# Shortend length of an extra long entry in the dates/space file. <cdurst@aecmail.prime.com>
  85. X# Fixed bug in calculation of nth_day_of_month (shows up as putting election
  86. X#     day on the wrong week). <uunet.uu.net!formtek!pen>, <att.att.COM!cbosgd!smk>
  87. X# Fixed bug whereby deleted repeated appointments were not always recognized.
  88. X# Added #define for mail program with default set to "usr/ucb/mail". The
  89. X#     problem showed up when a user had /usr/5bin in his path before
  90. X#     /usr/ucb. <uunet.uu.net!cjsa!jeff>
  91. X# Fixed bug that caused calentool to dump core on notes sections with long messages.
  92. X# Added dates/space entry in Makefile.
  93. X# 
  94. X# =============
  95. X# New features:
  96. X# =============
  97. X# Modified parse_date to allow +nnn and -nnn syntax for dates relative to the
  98. X#     current date. <peter@hadrian.uwo.ca>
  99. X# 
  100. X# Add new #defines and switches for selected 12/24 time displays and either
  101. X#     Sunday-Saturday or Monday-Sunday weeks (for some Europeans). <hk@simulina.se>
  102. X# Cleaner opening windows. <cdurst@aecmail.prime.com>
  103. X# New -B option to beep AND open calentool window. <cdurst@aecmail.prime.com>
  104. X# Nested includes (to 4 levels) are now allowed. (Idea from <mdf0%shemesh@gte.COM>)
  105. X# Allow -p/-P[dw] options to work in conjunction with -m/-M so that a
  106. X#     weeks worth of appointments can be mailed.
  107. X# Added new expire option (-x) to expire (trash) all appointments older than
  108. X#     a specified number of days.
  109. X# The sense of the -w option was changed. In order to get the "Working!"
  110. X#     message, you now have to specify "-w".
  111. X# Changed M/D/Y dates to D/M/Y when European option (-E) selected.
  112. X# Optimized certain holiday calculations.
  113. X# New feature for appointments that repeat for a fixed interval of time
  114. X#       e.g. 12/26/89 for 5 days.
  115. X# Wrote new calencheck program for checking for pending appts without having
  116. X#     to run calentool.
  117. X#
  118. X# Revision 2.5  89/09/19  06:17:10  billr
  119. X# Patchlevel 4 of calentool. Fixes the following bug reports:
  120. X# 
  121. X# Bug fix in pcal.c for printing month of September <alexl@daemon.cna.tek.com>
  122. X# Bug fix for 386i machines when viewing long appointment strings <baron@neptune.cs.ucla.edu>
  123. X# Fix typos and clean up man page <rodgers@maxwell.mmwb.ucsf.edu>
  124. X# 
  125. X# Revision 2.4  89/08/11  08:34:47  billr
  126. X# Patchlevel 3 of calentool. Fixes the following bug reports:
  127. X# 
  128. X# Bug fix for moontool <kelvin%throop@acad.uucp>
  129. X# Bug fix/new version of passover() <amos@nsc.com>
  130. X# Bug in moon phase calculation <kent@tfd.com>, <ras@needle1.bellcore.com>, <roberts%studguppy@lanl.gov>, <darcic@lachlan.sts.te.com>
  131. X# Check return from get_defaults <ian@sq.com>
  132. X# Cleanup Makefile <casey@gauss.llnl.gov>
  133. X# Idea for monthly printout for terminal users <ian@sq.com>
  134. X# Makefile did not copy dates/computing to lib dir <jmc@ptsfa.pacbell.com>
  135. X# Missing arg for rotate function in ras2ps <jasmerb@hobbes.cs.orst.edu>
  136. X# More makefile cleanup <lwv27%chemabs@cis.ohio-state.edu>
  137. X# Off by one in mt2ct conversion <tom@cis.udel.edu>, <kas@cs.aber.ac.uk>, <paul%gill@uunet.uu.net>
  138. X# Optimize nr weeks calculation for month display <rwolff@noao.edu>
  139. X# Prevent calentool from sending mail when there are no appts <zander%trak@lanl.gov>, <john@math.nwu.edu>, <kayhan@cleopatra.usc.edu>
  140. X# Raster print command missing '-v' argument <hleroy@presto.irisa.fr>
  141. X# Scrambled moon icon on 386i <scott@cfi.com>, <lwv27%chemabs@cis.ohio-state.edu>, <syd@dsi.com>, <alfred@mcc.com>
  142. X# Seg fault when cursor moved to long appt entry (386i) <alfred@mcc.com>, <jmc@pbjmc.pacbell.com>, <baron@neptune.cs.ucla.edu>
  143. X# Set file access permissions on tmp file to match .appointments file <brooks@ge-dab.ge.com>
  144. X# Space date file <steve@prism.gatech.edu>
  145. X# Typo in man page "Save" file shoudl be "Update" file <lwv27%chemabs@cis.ohio-state.edu>
  146. X# Typo in riseset.c (tzp.minuteswest should be tzp.tz_minuteswest) <hleroy@presto.irisa.fr>, <correira@austin.lockheed.com>
  147. X# When deleteing an overlapping entry, background entry is not displayed <rgh@shell.uucp>
  148. X# Wrong week displayed when selecting a week in month display <rodgers@maxwell.mmwb.ucsf.edu>
  149. X#
  150. X# Revision 2.3  89/05/16  16:32:23  billr
  151. X# Fix bug whereby nfs mounted appointment files were not being
  152. X# properly updated.  Add support for PostScript pretty printing
  153. X# of a month's worth of appointments.
  154. X# 
  155. X# Revision 2.2  89/05/10  10:15:59  billr
  156. X# Fix bug relating to arrow count in the notes field.  It showed up when
  157. X# adding an additional note or pasting an appointment that overran its
  158. X# available timeslots.  Now at version 2.1, patchlevel 1 (V2.1p1).
  159. X# 
  160. X#
  161. X# Revision 2.1  89/05/09  10:13:56  billr
  162. X# release 2.1, patchlevel 0
  163. X# 
  164. END_OF_FILE
  165. if test 6274 -ne `wc -c <'Patches2_1'`; then
  166.     echo shar: \"'Patches2_1'\" unpacked with wrong size!
  167. fi
  168. # end of 'Patches2_1'
  169. fi
  170. if test -f 'datelib.c' -a "${1}" != "-c" ; then 
  171.   echo shar: Will not clobber existing file \"'datelib.c'\"
  172. else
  173. echo shar: Extracting \"'datelib.c'\" \(44896 characters\)
  174. sed "s/^X//" >'datelib.c' <<'END_OF_FILE'
  175. X/*
  176. X * $Header: datelib.c,v 2.5 91/01/30 12:45:28 billr Exp $
  177. X *
  178. X * datelib.c - Calendar (date) computation library
  179. X *
  180. X * R. P. C. Rodgers, UCSF, November 1988
  181. X * (with thanks to Greg Couch, Conrad Huang, and Dave Yee for their helpful
  182. X *  suggestions)
  183. X *
  184. X *        Copyright 1988, 1989 R. P. C. Rodgers,  All Rights Reserved
  185. X * Permission is granted by the author for use of this code under the following
  186. X * conditions: 1) improvements and corrections to this code are shared with the
  187. X * author; 2) the code is made freely available to anyone requesting it; 3) the
  188. X * code is not used for any profit-making venture without the express
  189. X * permission of the author; and, 3) all copies of the code will preserve the
  190. X * above authorship and copyright information and this notice.
  191. X *
  192. X * (requires math library)
  193. X * 
  194. X * Source of formulae:
  195. X * 
  196. X * 1) Schocken, Wolfgang Alexander
  197. X *    The calculated confusion of calendars; puzzles in Christian, Jewish and
  198. X *       Moslem calendars.
  199. X *    1st Ed.
  200. X *    Vantage Press
  201. X *    New York
  202. X *    1976
  203. X * 
  204. X * 2) Meeus, Jean
  205. X *    Astronomical Formulae for Calculators
  206. X *    Monografieen over Astronomie en Astrofysica
  207. X *    Volkssterrenwacht Urania V.Z.W.
  208. X *    Mattheessensstraat 62, B 2540 Hove, Belgium
  209. X *    Vereniging voor Sterrenkunde V.Z.W.
  210. X *    Ringlaan 3, B 1180 Brussel, Belgium
  211. X *    Vol. 4
  212. X *    Derde Druk
  213. X *    October 1980
  214. X *    (3rd edition of 1985 available from Willmann-Bell, address below)
  215. X *    (formulae for Easter, Julian and Gregorian date formation, and
  216. X *     solstices/equinoxes)
  217. X * 
  218. X * 3) Assorted contributions to the Hewlett-Packard HP-41C Software Library
  219. X * 
  220. X * In his 1987 Sun program "moontool," John Walker (Autodesk, Sausalito, CA)
  221. X * mentions several other potentially useful references:
  222. X * 
  223. X * 4) Pierre Bretagnon and Jean-Louis Simon
  224. X *    Planetary Programs and Tables from -4000 to +2800
  225. X *    Willmann-Bell
  226. X *    1986
  227. X *    (for utmost accuracy in planetary computations)
  228. X * 
  229. X * 5) Eric Burgess
  230. X *    Celestial BASIC
  231. X *    Revised Edition
  232. X *    Sybex
  233. X *    1985
  234. X *    (cookbook oriented, many algorithms hard to dig out of turgid BASIC)
  235. X * 
  236. X * Many of these references can be obtained from Willmann-Bell, P.O. Box
  237. X * 35025, Richmond, VA 23235, USA.  Phone: (804) 320-7016.  In addition
  238. X * to their own publications, they stock most of the standard references
  239. X * for mathematical and positional astronomy.
  240. X * 
  241. X * NOTES:
  242. X * check ranges on days (0-365)
  243. X * islamic new year and jewish dates not thoroughly tested
  244. X * 
  245. X */
  246. X
  247. X#include "ct.h"        /* for the NO_HOLIDAYS #define */
  248. X
  249. X#include    <stdio.h>    /* for NULL */
  250. X#include    <math.h>
  251. X
  252. Xdouble    julian_day();
  253. X
  254. X#ifndef NO_HOLIDAYS
  255. Xextern    char    *malloc();
  256. Xdouble  easter_offset(), passover_offset();
  257. X
  258. Xstatic char    *monthname[] = { 
  259. X        "January", "February", "March", "April", "May",
  260. X        "June", "July", "August", "September",
  261. X        "October", "November", "December"    };
  262. Xstatic char    *dayname[] = { 
  263. X        "Sunday", "Monday", "Tuesday", "Wednesday",
  264. X        "Thursday", "Friday", "Saturday"    };
  265. Xstatic char    timebuf[16];
  266. Xstatic double    passoverJD, easterJD;
  267. Xstatic int    passoverJY;
  268. X
  269. X/*
  270. X * date_string:
  271. X * Return date string of form: "Monday 12 December 1988"
  272. X * given day of week (0-6), day (1-31), month (1-12), year
  273. X */
  274. Xchar *
  275. Xdate_string(day_of_week, day, month, year)
  276. X    double    day;
  277. X    int    day_of_week, month, year;
  278. X{
  279. X    char *date;
  280. X
  281. X    date = (char *) malloc(81 * sizeof(char));
  282. X    if (date == NULL)
  283. X        err_rpt("out of memory", FATAL);
  284. X    (void) sprintf(date, "%s %d %s %d",
  285. X        dayname[day_of_week], (int) day, monthname[--month], year);
  286. X    return date;
  287. X}
  288. X
  289. X/*
  290. X * date_string_2:
  291. X * Return date string of form: "Monday 12 December 1988 (NYEAR)"
  292. X * given day of week (0-6), day (1-31), month (1-12), year, and alternate
  293. X * (that is, non-Gregorian) year, NYEAR
  294. X */
  295. Xchar *
  296. Xdate_string_2(day_of_week, day, month, year, nyear)
  297. X    double    day;
  298. X    int    day_of_week, month, nyear, year;
  299. X{
  300. X    char *date;
  301. X
  302. X    date = (char *) malloc(81 * sizeof(char));
  303. X    if (date == NULL)
  304. X        err_rpt("out of memory", FATAL);
  305. X    (void) sprintf(date, "%s %d %s %d (%d)",
  306. X        dayname[day_of_week], (int) day, monthname[--month],
  307. X            year, nyear);
  308. X    return date;
  309. X}
  310. X
  311. X/*
  312. X * date_time_string:
  313. X * Return date/time string of form: "10:42 Monday 12 December 1988"
  314. X * given hour (0-24), minute (0-59), day of week (0-6), day (1-31),
  315. X * month (1-12), year
  316. X */
  317. Xchar *
  318. Xdate_time_string(hour, min, day_of_week, day, month, year)
  319. X    double    day;
  320. X    int    day_of_week, hour, min, month, year;
  321. X{
  322. X    char *date;
  323. X
  324. X    date = (char *) malloc(81 * sizeof(char));
  325. X    if (date == NULL)
  326. X        err_rpt("out of memory", FATAL);
  327. X    (void) sprintf(date, "%02d:%02d %s %d %s %d",
  328. X        hour, min, dayname[day_of_week], (int) day,
  329. X        monthname[--month], year);
  330. X    return date;
  331. X}
  332. X
  333. X/*
  334. X * election_day:
  335. X * Compute date of Election Day given year (1584-9999)
  336. X * Election day is defined as the first Tuesday following the first
  337. X * Monday in November.
  338. X */
  339. Xdouble
  340. Xelection_day(year)
  341. X    int    year;
  342. X{
  343. X    double day, nth_mday_of_month();
  344. X
  345. X    /* find first Tuesday in Nov. */
  346. X    day = nth_mday_of_month(1, 2, 11, year);
  347. X    /* if it's the first day of the month then Election day is next week */
  348. X    if (day == 1.)
  349. X        day = 8.;
  350. X    return julian_day(day, 11, year);
  351. X}
  352. X
  353. X/*
  354. X * dday2:
  355. X * Compute dday2 for various holiday routines given x value, year (>1583)
  356. X */
  357. Xdday2(x, year)
  358. X    int    x, year;
  359. X{
  360. X    int    atmp, btmp;
  361. X
  362. X    atmp = 1.25 * year;
  363. X    btmp = year / 100;
  364. X    btmp = 0.75 * (1 + btmp);
  365. X    return (x + atmp - btmp) % 7;
  366. X}
  367. X#endif    /* NO_HOLIDAYS */
  368. X
  369. X/*
  370. X * days_remaining_in_year:
  371. X * Compute remaining days of year (0-365)
  372. X * given day (1-31), month (1-12), year (1901-2009)
  373. X */
  374. Xdays_remaining_in_year(day, month, year)
  375. X    double    day;
  376. X    int    month, year;
  377. X{
  378. X    int    length_of_year(), day_of_year();
  379. X
  380. X    return length_of_year(year) - day_of_year(day, month, year);
  381. X}
  382. X
  383. X/*
  384. X * length_of_year:
  385. X * Compute days in year (365 or 366)
  386. X * given year (1901-2009)
  387. X */
  388. Xlength_of_year(year)
  389. X    int    year;
  390. X{
  391. X    int    ylength;
  392. X
  393. X    if ((year % 400) == 0)
  394. X        ylength = 366;
  395. X    else if ((year % 100) == 0)
  396. X        ylength = 365;
  397. X    else if ((year % 4) == 0)
  398. X        ylength = 366;
  399. X    else
  400. X        ylength = 365;
  401. X    return ylength;
  402. X}
  403. X
  404. X/*
  405. X * get_day_of_week:
  406. X * Compute day of week (0-6 for Sunday-Saturday)
  407. X * given day (1-31), month (1-12), year (1901-2009)
  408. X */
  409. Xget_day_of_week(day, month, year)
  410. X    double    day;
  411. X    int    month, year;
  412. X{
  413. X    int    atmp;
  414. X
  415. X    atmp = julian_day(day, month, year) + 1.5;
  416. X    return atmp % 7;
  417. X}
  418. X
  419. X/*
  420. X * day_of_year:
  421. X * Compute day of year (1-366)
  422. X * given day (1-31), month (1-12), year (1901-2009)
  423. X */
  424. Xday_of_year(day, month, year)
  425. X    double    day;
  426. X    int    month, year;
  427. X{
  428. X    return (int) julian_day(day, month, year)
  429. X        - (int) julian_day(0.0, 1, year);
  430. X}
  431. X
  432. X/*
  433. X * nth_mday_of_month:
  434. X * Compute nth m-day of the month (1-31)
  435. X * given n (1-5), day of week (0-6, 0 for Sunday), month (1-12),
  436. X * year (1583-9999)
  437. X */
  438. Xdouble
  439. Xnth_mday_of_month(n, day_of_week, month, year)
  440. X    int    day_of_week, month, n, year;
  441. X{
  442. X    int    atmp, btmp, ctmp, dtmp, etmp, tmonth, tyear;
  443. X
  444. X    if (month > 2) {
  445. X        tmonth = month + 1;
  446. X        tyear = year;
  447. X    }
  448. X    else {
  449. X        tmonth = month + 13;
  450. X        tyear = year - 1;
  451. X    }
  452. X    atmp = 2.6 * tmonth;
  453. X    btmp = 1.25 * tyear;
  454. X    ctmp = (tyear / 100) - 7;
  455. X    dtmp = 0.75 * ctmp;
  456. X    etmp = (day_of_week - atmp - btmp + dtmp) % 7;
  457. X    return (double) (etmp + (n * 7));
  458. X}
  459. X
  460. X/*
  461. X * julian_day:
  462. X * Compute Julian day (>=1)
  463. X * given day (1-31), month (1-12), year (1901-2009)
  464. X *
  465. X * Notes: The Gregorian reform is taken into account (that is, the day
  466. X * following 4 October 1582 is 15 October 1582; dates on this latter day or
  467. X * later are said to be in the Gregorian calendar).  B.C. years are counted
  468. X * astronomically (the year prior to year 1 is year 0).  The Julian day
  469. X * begins at GMT noon (the day is expressed in floating point).
  470. X * Example: to obtain Julian day for 4 Jul 1979: julian_day(4.0, 7, 1979)
  471. X */
  472. Xdouble
  473. Xjulian_day(day, month, year)
  474. X    double    day;
  475. X    int    month, year;
  476. X{
  477. X    int    atmp, monthp, yearp;
  478. X    double    ctmp = 1720994.5 + day;
  479. X
  480. X    if (month > 2) {
  481. X        monthp = month + 1;
  482. X        yearp = year;
  483. X    }
  484. X    else {
  485. X        monthp = month + 13;
  486. X        yearp = year - 1;
  487. X    }
  488. X    if ((year > 1582) || (year == 1582 && month >= 10)
  489. X        || (year == 1582 && month == 10 && day >= 15)) {
  490. X        atmp = year / 100;
  491. X        ctmp += 2 - atmp + (int)(atmp / 4);
  492. X    }
  493. X    ctmp += (int)(365.25 * yearp) + (int)(30.6001 * monthp);
  494. X    return ctmp;
  495. X}
  496. X
  497. X#ifndef NO_HOLIDAYS
  498. X/*
  499. X * datelib_int:
  500. X * Calculate often used quantities (e.g. Easter, Passover) as an
  501. X * optimization.
  502. X */
  503. Xdatelib_init(year)
  504. X    int    year;
  505. X{
  506. X    void passover_init(), easter_init();
  507. X
  508. X    easter_init(year);
  509. X    passover_init(year);
  510. X}
  511. X
  512. X/*
  513. X * corrected_julian_day:
  514. X * Correct Julian day (>=1) for conversion from JULIAN CALENDAR
  515. X * to GREGORIAN CALENDAR.
  516. X */
  517. Xdouble
  518. Xcorrected_julian_day(jday)
  519. X    double    jday;
  520. X{
  521. X    double    day;
  522. X    int    atmp, btmp, month, year;
  523. X
  524. X    gregorian_date(&day, &month, &year, jday);
  525. X    atmp = year / 100;
  526. X    btmp = ((3 * atmp) - 5) / 4;
  527. X    return julian_day(day, month, year) + btmp;
  528. X}
  529. X
  530. X/*
  531. X * gregorian_date:
  532. X * Return pointers to day (1-31), month (1-12), year (1901-2009),
  533. X * given Julian day (>=0)
  534. X *
  535. X * Notes: The Gregorian reform is taken into account (that is, the day
  536. X * following 4 October 1582 is 15 October 1582; dates on this latter day or
  537. X * later are said to be in the Gregorian calendar).  B.C. years are counted
  538. X * astronomically (the year prior to year 1 is year 0).  The Julian day
  539. X * begins at GMT noon.  The Julian day can be expressed in
  540. X * floating point below to get a day result with decimal places.  This method
  541. X * is valid only for positive Julian day numbers.
  542. X */
  543. Xgregorian_date(p_day, p_month, p_year, jday)
  544. X    int    *p_month, *p_year;
  545. X    double    *p_day, jday;
  546. X{
  547. X    int    atmp, btmp, ctmp, dtmp, etmp, gtmp, ztmp;
  548. X    double    ftmp;
  549. X
  550. X    ztmp = jday + 0.5;
  551. X    ftmp = (jday + 0.5) - ztmp;
  552. X    if (ztmp >= 2299161) {
  553. X        gtmp = (ztmp - 1867216.25) / 36524.25;
  554. X        ctmp = gtmp / 4;
  555. X        atmp = ztmp + 1 + gtmp - ctmp;
  556. X    }
  557. X    else
  558. X        atmp = ztmp;
  559. X    btmp = atmp + 1524;
  560. X    ctmp = (btmp - 122.1) / 365.25;
  561. X    dtmp = 365.25 * ctmp;
  562. X    etmp = ((btmp - dtmp) / 30.6001);
  563. X    ztmp = 30.6001 * etmp;
  564. X    *p_day = btmp - dtmp - ztmp + ftmp;
  565. X    if (etmp > 13.5)
  566. X        *p_month = etmp - 13;
  567. X    else
  568. X        *p_month = etmp - 1;
  569. X    if (*p_month > 2.5)
  570. X        *p_year = ctmp - 4716;
  571. X    else
  572. X        *p_year = ctmp - 4715;
  573. X}
  574. X
  575. X/*
  576. X * mdays_between_dates:
  577. X * Compute number of mdays between two dates (exclusive: don't count the
  578. X * days themselves) given day of week (0-6, O for Sunday),
  579. X * two sets of day (1-31), month (1-12), year (1583-9999)
  580. X */
  581. Xmdays_between_dates(day_of_week, day1, month1, year1, day2, month2, year2)
  582. X    int    day_of_week, month1, year1, month2, year2;
  583. X    double    day1, day2;
  584. X{
  585. X    return wday(day_of_week, day2, month2, year2)
  586. X        - wday(day_of_week, day1, month1, year1);
  587. X}
  588. X
  589. X/*
  590. X * years_date_is_mday:
  591. X * Compute year(s) for which a given date is an m-day
  592. X * given starting year, ending year,
  593. X * day of week (0-6, 0 for Sunday), day, and month
  594. X * algorithm said to be valid for 1 Mar 1900 to 28 Feb 2100.
  595. X */
  596. Xyears_date_is_mday(day_of_week, day, month, start_year, end_year, yearlist,
  597. X    number_of_years)
  598. X    int    day_of_week, end_year, month, *number_of_years, yearlist[],
  599. X        start_year;
  600. X    double    day;
  601. X{
  602. X    int        diff, index, year, tdow;
  603. X    static int    augment[] = {6, 11, 6, 5}; 
  604. X
  605. X    *number_of_years = 0;
  606. X    if (start_year > end_year) return -1;
  607. X    for (year = start_year; year <= end_year; year++ ) {
  608. X        tdow = get_day_of_week(day, month, year);
  609. X        if (tdow == day_of_week) {
  610. X            yearlist[(*number_of_years)++] = year;
  611. X        }
  612. X        if (*number_of_years == 2 || *number_of_years == 3) {
  613. X            diff = yearlist[*number_of_years]
  614. X                - yearlist[*number_of_years - 1];
  615. X            if (diff == 5) {
  616. X                year++;
  617. X                index = 0;
  618. X                break;
  619. X            }
  620. X            else if (diff == 11) {
  621. X                year++;
  622. X                index = 2;
  623. X                break;
  624. X            }
  625. X        }
  626. X    }
  627. X    for ( ; year <= end_year; year++ ) {
  628. X        yearlist[(*number_of_years + 1)] =
  629. X            yearlist[*number_of_years] + augment[index++ % 4];
  630. X        (*number_of_years)++;
  631. X    }
  632. X    return 0;
  633. X}
  634. X
  635. X/*
  636. X * weekdays_between_dates:
  637. X * Compute weekdays between any two dates
  638. X * given two sets of day (1-31), month (1-12), year (1901-2009)
  639. X */
  640. Xweekdays_between_dates(day1, month1, year1, day2, month2, year2)
  641. X    int    month1, month2, year1, year2;
  642. X    double    day1, day2;
  643. X{
  644. X    return wday2(day2, month2, year2) - wday2(day1, month1, year1);
  645. X}
  646. X
  647. X/*
  648. X * wday:
  649. X * Compute wday for mdays_between_dates routine
  650. X * given day of week, day, month, year
  651. X */
  652. Xwday(day_of_week, day, month, year)
  653. X    int    day_of_week, month, year;
  654. X    double    day;
  655. X{
  656. X    int    atmp, btmp, ctmp, dtmp;
  657. X
  658. X    atmp = dday(day, month, year) - day_of_week;
  659. X    btmp = atmp / 7;
  660. X    ctmp = atmp % 7;
  661. X    dtmp = 0.11 * ctmp + 0.9;
  662. X    return btmp + (0.5 * dtmp);
  663. X}
  664. X
  665. X/*
  666. X * wday2:
  667. X * Compute wday2 for weekdays_between_dates routine
  668. X * given day, month, year
  669. X */
  670. Xwday2(day, month, year)
  671. X    int    month, year;
  672. X    double    day;
  673. X{
  674. X    int    atmp, btmp, ctmp, dtmp;
  675. X
  676. X    atmp = dday(day, month, year);
  677. X    btmp = atmp / 7;
  678. X    ctmp = atmp % 7;
  679. X    dtmp = 1.801 * ctmp;
  680. X    return (5 * btmp) + (0.5 * dtmp);
  681. X}
  682. X
  683. X/*
  684. X * dday:
  685. X * Compute dday for other routines
  686. X * given day (1-31), month (1-12), year (1901-2009)
  687. X */
  688. Xdday(day, month, year)
  689. X    int    month, year;
  690. X    double    day;
  691. X{
  692. X    int    atmp, btmp, ctmp, dtmp, tmonth, tyear;
  693. X
  694. X    if (month > 2) {
  695. X        tmonth = month + 1;
  696. X        tyear = year;
  697. X    }
  698. X    else {
  699. X        tmonth = month + 13;
  700. X        tyear = year - 1;
  701. X    }
  702. X    atmp = tyear / 100;
  703. X    btmp = 0.75 * (atmp - 7);
  704. X    ctmp = 365.25 * tyear;
  705. X    dtmp = 30.6001 * tmonth;
  706. X    return (int) day - btmp + ctmp + dtmp;
  707. X}
  708. X
  709. X/*
  710. X * vernal_equinox:
  711. X * Compute Julian day for Vernal (March) Equinox given year (1901-2009)
  712. X */
  713. Xdouble
  714. Xvernal_equinox(year)
  715. X    int    year;
  716. X{
  717. X    double    solstice_equinox_exact();
  718. X
  719. X    return solstice_equinox_exact(0, year);
  720. X}
  721. X
  722. X/*
  723. X * summer_solstice:
  724. X * Compute Julian day for Summer Solstice (June) given year (1901-2009)
  725. X */
  726. Xdouble
  727. Xsummer_solstice(year)
  728. X    int    year;
  729. X{
  730. X    double    solstice_equinox_exact();
  731. X
  732. X    return solstice_equinox_exact(1, year);
  733. X}
  734. X
  735. X/*
  736. X * autumn_equinox:
  737. X * Compute Julian day for Autumnal (September) Equinox given year (1901-2009)
  738. X */
  739. Xdouble
  740. Xautumn_equinox(year)
  741. X    int    year;
  742. X{
  743. X    double    solstice_equinox_exact();
  744. X
  745. X    return solstice_equinox_exact(2, year);
  746. X}
  747. X
  748. X/*
  749. X * winter_solstice:
  750. X * Compute Julian day for Winter (December) Solstice given year (1901-2009)
  751. X */
  752. Xdouble
  753. Xwinter_solstice(year)
  754. X    int    year;
  755. X{
  756. X    double    day, jday;
  757. X    int    month, nyear;
  758. X    double    solstice_equinox_exact();
  759. X
  760. X    jday = solstice_equinox_exact(3, year);
  761. X    gregorian_date(&day, &month, &nyear, jday);
  762. X    if (nyear == year)
  763. X        return jday;
  764. X    else
  765. X        return solstice_equinox_exact(3, (year + 1));
  766. X}
  767. X
  768. X/*
  769. X * solstice_equinox__exact:
  770. X * Compute more precise date for Solstice/Equinox
  771. X * given code (0-3, 0 for Vernal Equinox), year (1901-2009)
  772. X */
  773. Xdouble
  774. Xsolstice_equinox_exact(code, year)
  775. X    int    code, year;
  776. X{
  777. X    int    count;
  778. X
  779. X    double    corr, jday_app;
  780. X    double    solstice_equinox_approx(), solstice_equinox_correction();
  781. X
  782. X    /* compute first approximation to Julian day */
  783. X    jday_app = solstice_equinox_approx(code-1, year);
  784. X    /* iteratively recompute corrected Julian day */
  785. X    for(count = 0; count < 15; count++) {
  786. X        corr = solstice_equinox_correction(jday_app, code);
  787. X        jday_app += corr;
  788. X        if (fabs(corr) < 0.00001)
  789. X            break;
  790. X    }
  791. X    return jday_app;
  792. X}
  793. X
  794. X/*
  795. X * solstice_equinox_correction:
  796. X * Compute correction for Solstice/Equinox Julian day
  797. X * approximate Julian day, code (0-3, 0 for Vernal Equinox)
  798. X */
  799. Xdouble
  800. Xsolstice_equinox_correction(jday, code)
  801. X    int    code;
  802. X    double    jday;
  803. X{
  804. X    double    apparent_longitude(), sin_degrees();
  805. X
  806. X    return(58.0 * sin_degrees((code * 90.0) - apparent_longitude(jday)));
  807. X}
  808. X
  809. X/*
  810. X * apparent_longitude:
  811. X * Compute apparent longitude (true equinox) of Sun for
  812. X * Solstice/Equinox given approximate Julian day
  813. X */
  814. Xdouble
  815. Xapparent_longitude(jday)
  816. X    double    jday;
  817. X{
  818. X    double    btmp, ctmp, dtmp, etmp, ftmp;
  819. X    double    sin_degrees();
  820. X
  821. X    btmp = (jday - 2415020.0) / 36525.0;    /* time in Julian centuries: */
  822. X                        /* epoch 0.5 January 1900 */
  823. X    ctmp = 279.69668 + (36000.76892 * btmp) /* geometric mean longitude */
  824. X        + (0.0003025 * btmp * btmp);    /* (mean equinox of the date) */
  825. X    dtmp = 358.47583 + (35999.04975 * btmp)    /* mean anomaly of Sun */
  826. X        + (0.00015 * btmp * btmp)
  827. X        + (0.0000033 * btmp * btmp * btmp);
  828. X    etmp = (1.919460 - (0.004789 * btmp)    /* Sun's eqn of the center */
  829. X        - (0.000014 * btmp)) * sin_degrees(dtmp)
  830. X        + (0.020094 - (0.0001 * btmp)) * sin_degrees(2 * dtmp)
  831. X        + 0.000293 * sin_degrees(3 * dtmp);
  832. X    ftmp = ctmp + etmp;            /* Sun's true longitude */
  833. X    return ftmp - 0.00569            /* app. long. of Sun */
  834. X        - 0.00479 * sin_degrees(259.18    /* (true equinox of the date) */
  835. X        - (1934.142 * btmp));
  836. X}
  837. X
  838. X/*
  839. X * sin_degrees:
  840. X * Compute sin for argument in degrees
  841. X */
  842. Xdouble
  843. Xsin_degrees(degrees)
  844. X#define    PI_CORR    0.01745329252                /* pi / 180 */
  845. X    double    degrees;
  846. X{
  847. X    return sin(degrees * PI_CORR);
  848. X}
  849. X
  850. X/*
  851. X * solstice_equinox_approx:
  852. X * Compute approximate date for Solstice/Equinox
  853. X * given code (0-3, 0 for Vernal Equinox), year (1901-2009)
  854. X */
  855. Xdouble
  856. Xsolstice_equinox_approx(code, year)
  857. X    int    code, year;
  858. X{
  859. X    return (365.2422 * (year + (code / 4))) + 1721141.3;
  860. X}
  861. X
  862. X/*
  863. X * easter:
  864. X * Return Julian date for Easter, given year (1901-2009)
  865. X *
  866. X * Offered in the book of Meeus, which cites:
  867. X *
  868. X * 1) Spencer Jones
  869. X *    General Astronomy
  870. X *    1922
  871. X *    pg. 73-74
  872. X *
  873. X * 2) Journal of the British Astronomical Association
  874. X *    Vol. 8
  875. X *    Pg. 91
  876. X *    Dec. 1977
  877. X *    (which attributes method to Butcher's Ecclesiastical Calendar of 1876)
  878. X *
  879. X * Method valid for all dates in the Gregorian calendar
  880. X * (from 15 October 1583 on)
  881. X */
  882. Xvoid
  883. Xeaster_init(year)
  884. X    int    year;
  885. X{
  886. X    double    day;
  887. X    int    atmp, btmp, ctmp, dtmp, etmp, ftmp,
  888. X        gtmp, htmp, itmp, ktmp, ltmp, mtmp;
  889. X    int    month;
  890. X
  891. X    atmp = year % 19;
  892. X    btmp = year / 100;
  893. X    ctmp = year % 100;
  894. X    dtmp = btmp / 4;
  895. X    etmp = btmp % 4;
  896. X    ftmp = (btmp + 8) / 25;
  897. X    gtmp = (btmp - ftmp + 1) / 3;
  898. X    htmp = ((19 * atmp) + btmp - dtmp - gtmp + 15) % 30;
  899. X    itmp = ctmp / 4;
  900. X    ktmp = ctmp % 4;
  901. X    ltmp = (32 + (2 * etmp) + (2 * itmp) - htmp - ktmp) % 7;
  902. X    mtmp = (atmp + (11 * htmp) + (22 * ltmp)) / 451;
  903. X    month = (htmp + ltmp - (7 * mtmp) + 114) / 31;
  904. X    day = ((htmp + ltmp - (7 * mtmp) + 114) % 31) + 1;
  905. X    easterJD = julian_day(day, month, year);
  906. X}
  907. X
  908. Xdouble
  909. Xeaster(year)
  910. X    int    year;
  911. X{
  912. X    return easterJD;
  913. X}
  914. X
  915. X/*
  916. X * first_sunday_advent:
  917. X * Christian holidays: compute Julian day for First Sunday in Advent
  918. X * (closest Sunday to St. Andrew's day, the last day in November)
  919. X * given year (>1583)
  920. X */
  921. Xdouble
  922. Xfirst_sunday_advent(year)
  923. X    int    year;
  924. X{
  925. X    int    atmp;
  926. X
  927. X    atmp = get_day_of_week(30.0, 11, year);
  928. X    if (atmp <= 3) {
  929. X        return julian_day((30.0 - (double) atmp), 11, year);
  930. X    }
  931. X    else {
  932. X        return julian_day(30.0, 11, year) + (7 - atmp);
  933. X    }
  934. X}
  935. X
  936. X/*
  937. X * easter_offset:
  938. X * Christian holidays: compute Julian day as offset from Easter
  939. X * given year (>1583)
  940. X */
  941. Xdouble
  942. Xeaster_offset(offset, year)
  943. X    double    offset;
  944. X    int    year;
  945. X{
  946. X    return easterJD + offset;
  947. X}
  948. X
  949. X/*
  950. X * septuagesima:
  951. X * Christian holidays: compute Julian day for Septuagesima Sunday
  952. X * (Third Sunday before Lent)
  953. X * given year (>1583)
  954. X */
  955. Xdouble
  956. Xseptuagesima(year)
  957. X    int    year;
  958. X{
  959. X    return easter_offset(-63.0, year);
  960. X}
  961. X
  962. X/*
  963. X * sexagesima:
  964. X * Christian holidays: compute Julian day for Sexagesima Sunday
  965. X * (Second Sunday before Lent)
  966. X * given year (>1583)
  967. X */
  968. Xdouble
  969. Xsexagesima(year)
  970. X    int    year;
  971. X{
  972. X    return easter_offset(-56.0, year);
  973. X}
  974. X
  975. X/*
  976. X * quinquagesima:
  977. X * Christian holidays: compute Julian day for Quinquagesima (Shrove) Sunday
  978. X * (Sunday before Lent begins on Ash Wednesday)
  979. X * given year (>1583)
  980. X */
  981. Xdouble
  982. Xquinquagesima(year)
  983. X    int    year;
  984. X{
  985. X    return easter_offset(-49.0, year);
  986. X}
  987. X
  988. X/*
  989. X * shrove_monday:
  990. X * Christian holidays: compute Julian day for Shrove Monday
  991. X * (Two days before Lent begins on Ash Wednesday)
  992. X * given year (>1583)
  993. X */
  994. Xdouble
  995. Xshrove_monday(year)
  996. X    int    year;
  997. X{
  998. X    return easter_offset(-48.0, year);
  999. X}
  1000. X
  1001. X/*
  1002. X * shrove_tuesday:
  1003. X * Christian holidays: compute Julian day for Shrove Tuesday
  1004. X * (Day before Lent begins on Ash Wednesday; Mardi Gras)
  1005. X * given year (>1583)
  1006. X */
  1007. Xdouble
  1008. Xshrove_tuesday(year)
  1009. X    int    year;
  1010. X{
  1011. X    return easter_offset(-47.0, year);
  1012. X}
  1013. X
  1014. X/*
  1015. X * ash_wednesday:
  1016. X * Christian holidays: compute Julian day for Ash Wednesday
  1017. X * given year (>1583)
  1018. X */
  1019. Xdouble
  1020. Xash_wednesday(year)
  1021. X    int    year;
  1022. X{
  1023. X    return easter_offset(-46.0, year);
  1024. X}
  1025. X
  1026. X/*
  1027. X * first_sunday_lent:
  1028. X * Christian holidays: compute Julian day for First Sunday in Lent
  1029. X * given year (>1583)
  1030. X */
  1031. Xdouble
  1032. Xfirst_sunday_lent(year)
  1033. X    int    year;
  1034. X{
  1035. X    return easter_offset(-42.0, year);
  1036. X}
  1037. X
  1038. X/*
  1039. X * second_sunday_lent:
  1040. X * Christian holidays: compute Julian day for Second Sunday in Lent
  1041. X * given year (>1583)
  1042. X */
  1043. Xdouble
  1044. Xsecond_sunday_lent(year)
  1045. X    int    year;
  1046. X{
  1047. X    return easter_offset(-35.0, year);
  1048. X}
  1049. X
  1050. X/*
  1051. X * third_sunday_lent:
  1052. X * Christian holidays: compute Julian day for Third Sunday in Lent
  1053. X * given year (>1583)
  1054. X */
  1055. Xdouble
  1056. Xthird_sunday_lent(year)
  1057. X    int    year;
  1058. X{
  1059. X    return easter_offset(-28.0, year);
  1060. X}
  1061. X
  1062. X/*
  1063. X * fourth_sunday_lent:
  1064. X * Christian holidays: compute Julian day for Fourth Sunday in Lent
  1065. X * given year (>1583)
  1066. X */
  1067. Xdouble
  1068. Xfourth_sunday_lent(year)
  1069. X    int    year;
  1070. X{
  1071. X    return easter_offset(-21.0, year);
  1072. X}
  1073. X
  1074. X/*
  1075. X * passion_sunday:
  1076. X * Christian holidays: compute Julian day for Passion Sunday
  1077. X * (Second Sunday before Easter)
  1078. X * given year (>1583)
  1079. X */
  1080. Xdouble
  1081. Xpassion_sunday(year)
  1082. X    int    year;
  1083. X{
  1084. X    return easter_offset(-14.0, year);
  1085. X}
  1086. X
  1087. X/*
  1088. X * palm_sunday:
  1089. X * Christian holidays: compute Julian day for Palm Sunday
  1090. X * (Sunday before Easter)
  1091. X * given year (>1583)
  1092. X */
  1093. Xdouble
  1094. Xpalm_sunday(year)
  1095. X    int    year;
  1096. X{
  1097. X    return easter_offset(-7.0, year);
  1098. X}
  1099. X
  1100. X/*
  1101. X * maundy_thursday:
  1102. X * Christian holidays: compute Julian day for Maundy Thursday
  1103. X * (Three days prior to Easter)
  1104. X * given year (>1583)
  1105. X */
  1106. Xdouble
  1107. Xmaundy_thursday(year)
  1108. X    int    year;
  1109. X{
  1110. X    return easter_offset(-3.0, year);
  1111. X}
  1112. X
  1113. X/*
  1114. X * good_friday:
  1115. X * Christian holidays: compute Julian day for Good Friday
  1116. X * (Two days prior to Easter)
  1117. X * given year (>1583)
  1118. X */
  1119. Xdouble
  1120. Xgood_friday(year)
  1121. X    int    year;
  1122. X{
  1123. X    return easter_offset(-2.0, year);
  1124. X}
  1125. X
  1126. X/*
  1127. X * easter_monday:
  1128. X * Christian holidays: compute Julian day for Easter Monday (Canada)
  1129. X * given year (>1583)
  1130. X */
  1131. Xdouble
  1132. Xeaster_monday(year)
  1133. X    int    year;
  1134. X{
  1135. X    return easter_offset(1.0, year);
  1136. X}
  1137. X
  1138. X/*
  1139. X * rogation_sunday:
  1140. X * Christian holidays: compute Julian day for Rogation Sunday
  1141. X * (Rogation is the period of three days prior to Ascension Day; strictly
  1142. X * speaking, this is the period Mon-Wed)
  1143. X * given year (>1583)
  1144. X */
  1145. Xdouble
  1146. Xrogation_sunday(year)
  1147. X    int    year;
  1148. X{
  1149. X    return easter_offset(35.0, year);
  1150. X}
  1151. X
  1152. X/*
  1153. X * ascension_day:
  1154. X * Christian holidays: compute Julian day for Ascension Day
  1155. X * (Holy Thursday; fortieth day after Easter, inclusive)
  1156. X * given year (>1583)
  1157. X */
  1158. Xdouble
  1159. Xascension_day(year)
  1160. X    int    year;
  1161. X{
  1162. X    return easter_offset(39.0, year);
  1163. X}
  1164. X
  1165. X/*
  1166. X * whitsunday:
  1167. X * Christian holidays: compute Julian day for Whitsunday (Pentecost)
  1168. X * (Seventh Sunday after Easter)
  1169. X * given year (>1583)
  1170. X */
  1171. Xdouble
  1172. Xwhitsunday(year)
  1173. X    int    year;
  1174. X{
  1175. X    return easter_offset(49.0, year);
  1176. X}
  1177. X
  1178. X/*
  1179. X * trinity_sunday:
  1180. X * Christian holidays: compute Julian day for Trinity Sunday
  1181. X * (Eighth Sunday after Easter)
  1182. X * given year (>1583)
  1183. X */
  1184. Xdouble
  1185. Xtrinity_sunday(year)
  1186. X    int    year;
  1187. X{
  1188. X    return easter_offset(56.0, year);
  1189. X}
  1190. X
  1191. X/*
  1192. X * corpus_christi:
  1193. X * Christian holidays: compute Julian day for Corpus Christi
  1194. X * (First Thursday after Trinity Sunday)
  1195. X * given year (>1583)
  1196. X */
  1197. Xdouble
  1198. Xcorpus_christi(year)
  1199. X    int    year;
  1200. X{
  1201. X    return easter_offset(60.0, year);
  1202. X}
  1203. X
  1204. X/*
  1205. X * passover:
  1206. X * Jewish holidays: compute Julian day of Pesach (first day of Passover)
  1207. X * and establish the Gregorian day of month and month, and Jewish year,
  1208. X * given Julian year (>1583)
  1209. X * This formula, due to Karl Friedrich Gauss (1777-1855) is described in
  1210. X * excruciating detail in the book by Schocken P. 51-61).  Note that it
  1211. X * computes the Julian date, which has to be corrected to a Gregorian date,
  1212. X * and that it exhibits the eccentricity of always computing the day
  1213. X * relative to March, so that April 2 appears as March 33, which is also
  1214. X * corrected below.
  1215. X *
  1216. X * Floating point implementation by R.P.C. Rodgers; integer implementation
  1217. X * (for faster calculation) by Amos Shapir (amos@nsc.com).
  1218. X */
  1219. Xvoid
  1220. Xpassover_init(year)
  1221. X    int    year;
  1222. X{
  1223. X    int    etmp, p_day;
  1224. X    int    atmp, btmp, ctmp, day_of_week, dtmp, ftmp, gtmp;
  1225. X    int    p_month;
  1226. X
  1227. X    atmp = year + 3760;
  1228. X    passoverJY = atmp;
  1229. X    btmp = (12 * atmp + 17) % 19;
  1230. X    ctmp = atmp % 4;
  1231. X    etmp = (765433 * btmp) - (1565 * atmp)
  1232. X        + (ctmp * 123120) + 15781075;
  1233. X    dtmp = etmp / 492480;
  1234. X    etmp %= 492480;
  1235. X        /* day_of_week is not to be confused with the
  1236. X         value returned by the day_of_week routine; here, Sunday = 1 */
  1237. X    day_of_week = ((3 * atmp) + (5 * ctmp) + dtmp + 5) % 7;
  1238. X    if (day_of_week == 0 && btmp > 11 && etmp >= 442111)
  1239. X        p_day = dtmp + 1;
  1240. X    else if (day_of_week == 1 && btmp > 6 && etmp >= 311676)
  1241. X        p_day = dtmp + 2;
  1242. X    else if (day_of_week == 2 || day_of_week == 4 || day_of_week ==6)
  1243. X        p_day = dtmp + 1;
  1244. X    else {
  1245. X        p_day = dtmp;
  1246. X    }
  1247. X    ftmp = year / 100;        /* Correct to Gregorian date */
  1248. X    gtmp = ((3 * ftmp) - 5) / 4;
  1249. X    p_day += gtmp;
  1250. X    if (p_day > 31) {        /* Correct for March days > 31 */
  1251. X        p_day -= 31;
  1252. X        p_month = 4;
  1253. X        }
  1254. X    else
  1255. X        p_month = 3;
  1256. X    passoverJD = julian_day((double)p_day, p_month, year);
  1257. X}
  1258. X
  1259. Xdouble
  1260. Xpassover(year, jyear)
  1261. X    int year, *jyear;
  1262. X{
  1263. X    *jyear = passoverJY;
  1264. X    return passoverJD;
  1265. X}
  1266. X
  1267. X/*
  1268. X * passover_offset:
  1269. X * Jewish holidays: compute Julian day as offset from Passover
  1270. X * given year (>1583)
  1271. X */
  1272. Xdouble
  1273. Xpassover_offset(offset, year, jyear)
  1274. X    double    offset;
  1275. X    int    *jyear, year;
  1276. X{
  1277. X    *jyear = passoverJY;
  1278. X    return passoverJD + offset;
  1279. X}
  1280. X
  1281. X/*
  1282. X * purim:
  1283. X * Jewish holidays: compute Julian day and Jewish year for Purim (Feast of Lots)
  1284. X * given year (>1583)
  1285. X */
  1286. Xdouble
  1287. Xpurim(year, jyear)
  1288. X    int    *jyear, year;
  1289. X{
  1290. X    return passover_offset(-30.0, year, jyear);
  1291. X}
  1292. X
  1293. X/*
  1294. X * shavuot:
  1295. X * Jewish holidays: compute Julian day and Jewish year for First day of Shavuot
  1296. X * given year (>1583)
  1297. X */
  1298. Xdouble
  1299. Xshavuot(year, jyear)
  1300. X    int    *jyear, year;
  1301. X{
  1302. X    return passover_offset(50.0, year, jyear);
  1303. X}
  1304. X
  1305. X/*
  1306. X * rosh_hashanah:
  1307. X * Jewish holidays: compute Julian day and Jewish year for first day of
  1308. X * Rosh Hashanah (New Year) given year (>1583)
  1309. X */
  1310. Xdouble
  1311. Xrosh_hashanah(year, jyear)
  1312. X    int    *jyear, year;
  1313. X{
  1314. X    double    atmp;
  1315. X    atmp = passover_offset(163.0, year, jyear);
  1316. X    (*jyear)++;
  1317. X    return atmp;
  1318. X}
  1319. X
  1320. X/*
  1321. X * yom_kippur:
  1322. X * Jewish holidays: compute Julian day and Jewish year for Yom Kippur
  1323. X * given year (>1583)
  1324. X */
  1325. Xdouble
  1326. Xyom_kippur(year, jyear)
  1327. X    int    *jyear, year;
  1328. X{
  1329. X    double    atmp;
  1330. X    atmp = passover_offset(172.0, year, jyear);
  1331. X    (*jyear)++;
  1332. X    return atmp;
  1333. X}
  1334. X
  1335. X/*
  1336. X * sukkot:
  1337. X * Jewish holidays: compute Julian day and Jewish year for
  1338. X * First day of Sukkot (9 days) given year (>1583)
  1339. X */
  1340. Xdouble
  1341. Xsukkot(year, jyear)
  1342. X    int    *jyear, year;
  1343. X{
  1344. X    double    atmp;
  1345. X    atmp = passover_offset(177.0, year, jyear);
  1346. X    (*jyear)++;
  1347. X    return atmp;
  1348. X}
  1349. X
  1350. X/*
  1351. X * simchat_torah:
  1352. X * Jewish holidays: compute Julian day and Jewish year for Simchat Torah
  1353. X * (in Diapsora) given year (>1583)
  1354. X */
  1355. Xdouble
  1356. Xsimchat_torah(year, jyear)
  1357. X    int    *jyear, year;
  1358. X{
  1359. X    double    atmp;
  1360. X    atmp = passover_offset(185.0, year, jyear);
  1361. X    (*jyear)++;
  1362. X    return atmp;
  1363. X}
  1364. X
  1365. X/*
  1366. X * chanukah:
  1367. X * Jewish holidays: compute Julian day and Jewish year for
  1368. X * first day of Chanukah (8 days) given year (>1583)
  1369. X */
  1370. Xdouble
  1371. Xchanukah(year, jyear)
  1372. X    int    *jyear, year;
  1373. X{
  1374. X    double    atmp, ptmp;
  1375. X    int    btmp, ytmp;
  1376. X
  1377. X    atmp = passover(year, jyear);
  1378. X    /* we need top compute passover for next year, so
  1379. X     * save current info and restore when done
  1380. X     */
  1381. X    ptmp = passoverJD;
  1382. X    ytmp = passoverJY;
  1383. X    passover_init(year + 1);
  1384. X    btmp = passoverJD - atmp;
  1385. X    passoverJD = ptmp;
  1386. X    passoverJY = ytmp;
  1387. X    (*jyear)++;
  1388. X    if (btmp == 355 || btmp == 385)
  1389. X        return atmp + 247.0;
  1390. X    else
  1391. X        return atmp + 246.0;
  1392. X}
  1393. X
  1394. X/*
  1395. X * islamic_date:
  1396. X * Islamic holidays: compute Gregorian date(s) and Islamic year for any
  1397. X * Islamic day, given ISLAMIC day (1-30), ISLAMIC month(1-12),
  1398. X * and GREGORIAN year (>1583)
  1399. X * This is complicated by the fact that a given Islamic date can appear as
  1400. X * often as twice within the same Gregorian year.
  1401. X */
  1402. Xislamic_date(
  1403. X    mday, mmonth, number_of_days, day1, month1, day2, month2, year, myear1,
  1404. X    myear2)
  1405. X    double    *day1, *day2, mday;
  1406. X    int    mmonth, *month1, *month2, *myear1, *myear2,
  1407. X        *number_of_days, year;
  1408. X{
  1409. X    double    day;
  1410. X    int    count, month, nyear;
  1411. X    double    islamic_to_julian();
  1412. X
  1413. X    *myear1 = year - 621;        /* approx. >= Muslim year */
  1414. X    nyear = year - 1;
  1415. X    for (count = 0; nyear != year && count <= 100; count++) {
  1416. X        gregorian_date(&day, &month, &nyear,
  1417. X            islamic_to_julian(mday, mmonth, *myear1));
  1418. X        *myear1 = *myear1 + (year - nyear);
  1419. X    }
  1420. X    if (nyear == year) {
  1421. X        *day1 = day;
  1422. X        *month1 = month;
  1423. X        /*
  1424. X         * See if there is a second occurrence in same Gregorian year
  1425. X         */
  1426. X        gregorian_date(&day, &month, &nyear,
  1427. X            islamic_to_julian(mday, mmonth, (*myear1 + 1)));
  1428. X        if (nyear == year) {
  1429. X            *day2 = day;
  1430. X            *month2 = month;
  1431. X            *number_of_days = 2;
  1432. X            *myear2 = *myear1 + 1;
  1433. X        }
  1434. X        else {
  1435. X            *number_of_days = 1;
  1436. X            gregorian_date(&day, &month, &nyear,
  1437. X                islamic_to_julian(mday, mmonth, (*myear1 - 1)));
  1438. X            if (nyear == year) {
  1439. X                *day2 = day;
  1440. X                *month2 = month;
  1441. X                *number_of_days = 2;
  1442. X                *myear2 = *myear1 + 1;
  1443. X            }
  1444. X        }
  1445. X    }
  1446. X/*    else return -1; */
  1447. X    return 0;
  1448. X}
  1449. X
  1450. X/*
  1451. X * islamic_to_julian:
  1452. X * Islamic holidays: compute Julian day for any Islamic day,
  1453. X * given ISLAMIC day (1-30), ISLAMIC month(1-12), and ISLAMIC year (>962)
  1454. X * Formula from Schocken (p. 66)
  1455. X */
  1456. Xdouble
  1457. Xislamic_to_julian(mday, mmonth, myear)
  1458. X    double    mday;
  1459. X    int    mmonth, myear;
  1460. X{
  1461. X    double    etmp, ftmp, jday;
  1462. X    int    atmp, btmp, ctmp, dtmp, nyear;
  1463. X    double    corrected_julian_day();
  1464. X
  1465. X    nyear = myear + 621;        /* approx. Julian year */
  1466. X    atmp = ((19 * myear) - 4) % 30;
  1467. X    btmp = nyear % 4;
  1468. X    ctmp = (mmonth - 1) / 2;
  1469. X    dtmp = (mmonth - 1) % 2;
  1470. X    etmp = mday + (59.0 * ctmp) + (30.0 * dtmp) + (atmp / 30.0)
  1471. X         + (btmp / 4.0) - (10.8833333 * myear) + 146.8833333;
  1472. X    if (etmp < 0.0) {
  1473. X        ftmp = (4.0 * fabs(etmp)) / 1461.0;
  1474. X        atmp = ftmp;
  1475. X        dtmp = (4.0 * fabs(etmp));
  1476. X        dtmp = dtmp % 1461;
  1477. X        nyear -= (atmp + 1);
  1478. X        ctmp = nyear % 4;
  1479. X        jday = julian_day(1.0, 3, nyear)
  1480. X            + (((1461.0 - dtmp) + ctmp - btmp) / 4.0)
  1481. X            - 1.0;
  1482. X        return corrected_julian_day(jday);
  1483. X    }
  1484. X    jday = julian_day(1.0, 3, nyear) + etmp - 1.0;
  1485. X    return corrected_julian_day(jday);
  1486. X}
  1487. X
  1488. X/*
  1489. X * islamic_new_year:
  1490. X * Islamic holidays: compute Julian date(s) and Islamic year(s)
  1491. X * for Islamic New Year given JULIAN year (>1583)
  1492. X * (note: due to the length of the Islamic year (355 d), there can be portions
  1493. X * of as many as two Islamic New Years within a given Gregorian year; for
  1494. X * example, according to the algorithm below, the Islamic New Year occured
  1495. X * twice in 1975: Wednesday 1 January, Sunday 21 December)
  1496. X *
  1497. X * Algorithm: Schocken, page 66, which agrees with dates I have obtained for
  1498. X * the (Gregorian) years 1962-2000.  Schocken outlines a Muslim calendar
  1499. X * consisting of 12 months which are alternately 30 and 29 days in length
  1500. X * (the first month, Muharram, is 30 days in length).  In a 30-year cycle,
  1501. X * there are 11 leap years in which a 30th day is added to the final month
  1502. X * of the year.  See full details below.
  1503. X *
  1504. X * According to Dr. Omar Afzal of Cornell University ((607)255-5118,
  1505. X * 277-6707; Chairman of the Committee for Crescent Observation;
  1506. X * irfan@mvax.ee.cornell.edu), this is an antiquated system which has been
  1507. X * in use for some 400 years, but today the Muslim calendar follows a more
  1508. X * strictly lunar basis.  I wish to acknowledge the Pakistani Consular
  1509. X * Office of San Francisco (415)788-0677, who referred me to Dr. Muzammil
  1510. X * Siddiqui of the Orange County Islamic Center, (714)531-1722, who in turn
  1511. X * referred me to to Dr. Afzal.  I thank Dr. Afzal for his patient and lucid
  1512. X * explanations of the Islamic calendar, and for providing printed matter and
  1513. X * tables of dates to assist me.  Among the sources he provided:
  1514. X *
  1515. X * %A U. V. Tsybulsky
  1516. X * %B Calendar of Middle Eastern Countries
  1517. X * %I Nauka Publishing House
  1518. X * %C Moscow
  1519. X * %L English
  1520. X * %D 1979
  1521. X *
  1522. X * which provides a scholarly discussion of calendrical conventions in various
  1523. X * Muslim countries, as well as simple formulas for conversion between
  1524. X * Gregorian and Islamic dates.  It also includes translations of tables which
  1525. X * originally appeared in:
  1526. X *
  1527. X * %A F. R. Unat
  1528. X * %B Hicri Tarihleri
  1529. X * %I Turktarih Kurumu Basimevi
  1530. X * %C Ankara
  1531. X * %L Turkish
  1532. X * %D 1959
  1533. X *
  1534. X * Additional tabular material is available in:
  1535. X *
  1536. X * %A G. S. P. Freeman-Grenville
  1537. X * %B The Muslim and Christian Calendars
  1538. X * %I Oxford University Press
  1539. X * %C London
  1540. X * %D 1963
  1541. X *
  1542. X * The Islamic calendar is also known as the Hijri calendar, and dates often
  1543. X * have "A.H." or "a.h." appended to them to indicate "Anno Hijri."  A
  1544. X * listing of the months and their lengths (in the old scheme):
  1545. X *
  1546. X *    Month Name     Days         Days to add to 1 Muharram to get 1st of month
  1547. X * 1  Muharram        30          0
  1548. X * 2  Safar           29         30
  1549. X * 3  Rabi' al-Awwal  30         59
  1550. X * 4  Rabi' ath-Thani 29         89
  1551. X * 5  Jumada al-Ula   30        118
  1552. X * 6  Jumada al-Akhir 29        148
  1553. X * 7  Rajab           30        177
  1554. X * 8  Sha'ban         29        207
  1555. X * 9  Ramadan         30        236
  1556. X * 10 Shawwal         29        266
  1557. X * 11 Dhul-Qa'da      30        295
  1558. X * 12 Dhul-Hijja      29 (30)   325
  1559. X *
  1560. X * In the old scheme, used here for simplicity, adherence to this set of rules
  1561. X * led to a gradual lag of the month behind the actual crescent moon.  Thus,
  1562. X * a leap day was appended to the final month in each of 11 years out of every
  1563. X * 30 year cycle: (2, 5, 7, 10, 13, 16, 18, 21, 24, 26, 29).  If the Hijra year
  1564. X * is divided by 30, and the remainder is equal to one of these numbers, it is
  1565. X * a leap year.
  1566. X *
  1567. X * The Islamic day begins after sunset, and the beginning of the month is tied
  1568. X * to the first VISIBLE appearance of the crescent moon, which often lags behind
  1569. X * the astronomical new moon.  Also, the crescent was sometimes computed
  1570. X * according to Mecca time.  There are numerous methods for defining the date
  1571. X * of the crescent moon (and hence calendar dates) among the various Muslim
  1572. X * regions of the world.  Given these uncertainties, the dates computed here are
  1573. X * likely to be accurate to only +/- 2 days.
  1574. X *
  1575. X * Any errors in this code are my own fault, and
  1576. X * not intended to offend any members of the Islamic faith.
  1577. X */
  1578. Xislamic_new_year(year, number_of_dates, date1, date2, myear1, myear2)
  1579. X    double    *date1, *date2;
  1580. X    int    *number_of_dates, *myear1, *myear2, year;
  1581. X{
  1582. X    double    day1, day2;
  1583. X    int    month1, month2;
  1584. X
  1585. X    if (islamic_date(1.0, 1, number_of_dates, &day1, &month1, &day2,
  1586. X        &month2, year, myear1, myear2) < 0) return -1;
  1587. X    *date1 = julian_day(day1, month1, year);
  1588. X    if (*number_of_dates == 2) *date2 = julian_day(day2, month2, year);
  1589. X    return 0;
  1590. X}
  1591. X
  1592. X/*
  1593. X * islamic_offset:
  1594. X * Islamic holidays: compute Julian day(s) for an Islamic date as an offset
  1595. X * from the Islamic New Year, given (Gregorian) year
  1596. X */
  1597. Xislamic_offset(offset, year, number_of_dates, date1, date2, myear1, myear2)
  1598. X    double    *date1, *date2, offset;
  1599. X    int    *number_of_dates, *myear1, *myear2, year;
  1600. X{
  1601. X    double    day, tdate1, tdate2;
  1602. X    int    month, tyear1, tyear2;
  1603. X
  1604. X    (void) islamic_new_year(year, number_of_dates, date1, date2,
  1605. X        myear1, myear2);
  1606. X    if (*number_of_dates == 2) {
  1607. X        tdate2 = *date2 + offset;
  1608. X        gregorian_date(&day, &month, &tyear2, tdate2);
  1609. X        if (tyear2 > year) {
  1610. X            tdate2 = *date1 + offset;
  1611. X            (void) islamic_new_year((year - 1), number_of_dates,
  1612. X                date1, date2, myear1, myear2);
  1613. X            tdate1 = *date1 + offset;
  1614. X            gregorian_date(&day, &month, &tyear1, tdate1);
  1615. X            if (tyear1 == year) {
  1616. X                *date1 = tdate1;
  1617. X                *date2 = tdate2;
  1618. X                *number_of_dates = 2;
  1619. X                *myear2 = *myear1 + 1;
  1620. X            }
  1621. X            else {
  1622. X                *date1 = tdate2;
  1623. X                *number_of_dates = 1;
  1624. X                *myear1 = *myear1 + 1;
  1625. X            }
  1626. X        }
  1627. X        else {
  1628. X            *date1 += offset;
  1629. X            *date2 = tdate2;
  1630. X        }
  1631. X    }
  1632. X    else {
  1633. X        tdate2 = *date1 + offset;
  1634. X        gregorian_date(&day, &month, &tyear2, tdate2);
  1635. X        if (tyear2 > year) {
  1636. X            (void) islamic_new_year((year - 1), number_of_dates,
  1637. X                date1, date2, myear1, myear2);
  1638. X            if (*number_of_dates == 2) {
  1639. X                *date1 = *date2 + offset;
  1640. X                *number_of_dates = 1;
  1641. X                *myear1 = *myear2;
  1642. X            }
  1643. X            else {
  1644. X                *date1 = *date1 + offset;
  1645. X            }
  1646. X        }
  1647. X        else {
  1648. X            (void) islamic_new_year((year - 1), number_of_dates,
  1649. X                date1, date2, myear1, myear2);
  1650. X            if (*number_of_dates == 2) {
  1651. X                tdate1 = *date2 + offset;
  1652. X                *myear1 = *myear2;
  1653. X            }
  1654. X            else {
  1655. X                tdate1 = *date1 + offset;
  1656. X            }
  1657. X            gregorian_date(&day, &month, &tyear1, tdate1);
  1658. X            if (tyear1 == year) {
  1659. X                *date1 = tdate1;
  1660. X                *date2 = tdate2;
  1661. X                *number_of_dates = 2;
  1662. X                *myear2 = *myear1 + 1;
  1663. X            }
  1664. X            else {
  1665. X                *date1 = tdate2;
  1666. X                *myear1 = *myear1 + 1;
  1667. X                *number_of_dates = 1;
  1668. X            }
  1669. X        }
  1670. X    }
  1671. X}
  1672. X
  1673. X/*
  1674. X * muharram_9:
  1675. X * Islamic holidays: compute Julian day(s) and Islamic year(s) for
  1676. X * Muharram 9 (Day of fasting) given year (>1583)
  1677. X */
  1678. Xmuharram_9(year, number_of_dates, date1, date2, myear1, myear2)
  1679. X    double    *date1, *date2;
  1680. X    int    *number_of_dates, *myear1, *myear2, year;
  1681. X{
  1682. X    islamic_offset(
  1683. X        8.0, year, number_of_dates, date1, date2, myear1, myear2);
  1684. X}
  1685. X
  1686. X/*
  1687. X * muharram_10:
  1688. X * Islamic holidays: compute Julian day(s) and Islamic year(s) for
  1689. X * Muharram 10 (Day of deliverance of Moses from the Pharoah; for Shia Islam,
  1690. X * martyrdom of Husain) given year (>1583)
  1691. X */
  1692. Xmuharram_10(year, number_of_dates, date1, date2, myear1, myear2)
  1693. X    double    *date1, *date2;
  1694. X    int    *number_of_dates, *myear1, *myear2, year;
  1695. X{
  1696. X    islamic_offset(
  1697. X        9.0, year, number_of_dates, date1, date2, myear1, myear2);
  1698. X}
  1699. X
  1700. X/*
  1701. X * muharram_16:
  1702. X * Islamic holidays: compute Julian day(s) and Islamic year(s) for
  1703. X * Muharram 16 (Imamat Day; Ismaili Khoja) given year (>1583)
  1704. X */
  1705. Xmuharram_16(year, number_of_dates, date1, date2, myear1, myear2)
  1706. X    double    *date1, *date2;
  1707. X    int    *number_of_dates, *myear1, *myear2, year;
  1708. X{
  1709. X    islamic_offset(
  1710. X        15.0, year, number_of_dates, date1, date2, myear1, myear2);
  1711. X}
  1712. X
  1713. X/*
  1714. X * eid_i_milad_un_nabi:
  1715. X * Islamic holidays: compute Julian day(s) and Islamic year(s) for
  1716. X * Rabi I 12 (Eid-i-Milad-un-Nabi: The Prophet's Birthday) given year (>1583)
  1717. X */
  1718. Xeid_i_milad_un_nabi(year, number_of_dates, date1, date2, myear1, myear2)
  1719. X    double    *date1, *date2;
  1720. X    int    *number_of_dates, *myear1, *myear2, year;
  1721. X{
  1722. X    islamic_offset(
  1723. X        70.0, year, number_of_dates, date1, date2, myear1, myear2);
  1724. X}
  1725. X
  1726. X/*
  1727. X * jumada_al_akhir_23:
  1728. X * Islamic holidays: compute Julian day(s) and Islamic year(s) for
  1729. X * Jumada al-Akhir 23 (Birth of Agha Khan IV, Ismaili) given year (>1583)
  1730. X */
  1731. Xjumada_al_akhir_23(year, number_of_dates, date1, date2, myear1, myear2)
  1732. X    double    *date1, *date2;
  1733. X    int    *number_of_dates, *myear1, *myear2, year;
  1734. X{
  1735. X    islamic_offset(
  1736. X        170.0, year, number_of_dates, date1, date2, myear1, myear2);
  1737. X}
  1738. X
  1739. X/*
  1740. X * shab_e_miraj:
  1741. X * Islamic holidays: compute Julian day(s) and Islamic year(s) for
  1742. X * Rajab 27 (Shab-e-Mi'raj: The Prophet's Ascension) given year (>1583)
  1743. X */
  1744. Xshab_e_miraj(year, number_of_dates, date1, date2, myear1, myear2)
  1745. X    double    *date1, *date2;
  1746. X    int    *number_of_dates, *myear1, *myear2, year;
  1747. X{
  1748. X    islamic_offset(
  1749. X        203.0, year, number_of_dates, date1, date2, myear1, myear2);
  1750. X}
  1751. X
  1752. X/*
  1753. X * shab_e_barat:
  1754. X * Islamic holidays: compute Julian day(s) and Islamic year(s) for
  1755. X * Shaban 15 (Shab-e-Bara't: Night, followed by day of fasting) given year (>1583)
  1756. X */
  1757. Xshab_e_barat(year, number_of_dates, date1, date2, myear1, myear2)
  1758. X    double    *date1, *date2;
  1759. X    int    *number_of_dates, *myear1, *myear2, year;
  1760. X{
  1761. X    islamic_offset(
  1762. X        221.0, year, number_of_dates, date1, date2, myear1, myear2);
  1763. X}
  1764. X
  1765. X/*
  1766. X * ramadan:
  1767. X * Islamic holidays: compute Julian day(s) and Islamic year(s) for
  1768. X * Ramadan 1 (Fasting month begins) given year (>1583)
  1769. X */
  1770. Xramadan(year, number_of_dates, date1, date2, myear1, myear2)
  1771. X    double    *date1, *date2;
  1772. X    int    *number_of_dates, *myear1, *myear2, year;
  1773. X{
  1774. X    islamic_offset(
  1775. X        236.0, year, number_of_dates, date1, date2, myear1, myear2);
  1776. X}
  1777. X
  1778. X/*
  1779. X * shab_e_qadr:
  1780. X * Islamic holidays: compute Julian day(s) and Islamic year(s) for
  1781. X * Ramadan 27 (Shab-e Qadr: Night vigil) given year (>1583)
  1782. X */
  1783. Xshab_e_qadr(year, number_of_dates, date1, date2, myear1, myear2)
  1784. X    double    *date1, *date2;
  1785. X    int    *number_of_dates, *myear1, *myear2, year;
  1786. X{
  1787. X    islamic_offset(
  1788. X        262.0, year, number_of_dates, date1, date2, myear1, myear2);
  1789. X}
  1790. X
  1791. X/*
  1792. X * eid_al_fitr:
  1793. X * Islamic holidays: compute Julian day(s) and Islamic year(s) for
  1794. X * Shawwal 1 (Eid-al-Fitr: Day of Feast) given year (>1583)
  1795. X */
  1796. Xeid_al_fitr(year, number_of_dates, date1, date2, myear1, myear2)
  1797. X    double    *date1, *date2;
  1798. X    int    *number_of_dates, *myear1, *myear2, year;
  1799. X{
  1800. X    islamic_offset(
  1801. X        266.0, year, number_of_dates, date1, date2, myear1, myear2);
  1802. X}
  1803. X
  1804. X/*
  1805. X * dhul_hijja_9:
  1806. X * Islamic holidays: compute Julian day(s) and Islamic year(s) for
  1807. X * Dhul-Hijj 9 (Day of Pilgrimage at Arafat, Mecca) given year (>1583)
  1808. X */
  1809. Xdhul_hijja_9(year, number_of_dates, date1, date2, myear1, myear2)
  1810. X    double    *date1, *date2;
  1811. X    int    *number_of_dates, *myear1, *myear2, year;
  1812. X{
  1813. X    islamic_offset(
  1814. X        333.0, year, number_of_dates, date1, date2, myear1, myear2);
  1815. X}
  1816. X
  1817. X/*
  1818. X * eid_al_adha:
  1819. X * Islamic holidays: compute Julian day(s) and Islamic year(s) for
  1820. X * Dhul-Hijj 10 (Eid-al-Adha: Day of Abraham's Sacrifice) given year (>1583)
  1821. X */
  1822. Xeid_al_adha(year, number_of_dates, date1, date2, myear1, myear2)
  1823. X    double    *date1, *date2;
  1824. X    int    *number_of_dates, *myear1, *myear2, year;
  1825. X{
  1826. X    islamic_offset(
  1827. X        334.0, year, number_of_dates, date1, date2, myear1, myear2);
  1828. X}
  1829. X
  1830. X/*
  1831. X * ghadir:
  1832. X * Islamic holidays: compute Julian day(s) and Islamic year(s) for
  1833. X * Dhul-Hijj 18 (Ghadir: Ali's Nomination) given year (>1583)
  1834. X */
  1835. Xghadir(year, number_of_dates, date1, date2, myear1, myear2)
  1836. X    double    *date1, *date2;
  1837. X    int    *number_of_dates, *myear1, *myear2, year;
  1838. X{
  1839. X    islamic_offset(
  1840. X        342.0, year, number_of_dates, date1, date2, myear1, myear2);
  1841. X}
  1842. X
  1843. X/*
  1844. X * print_islamic_string:
  1845. X * Print formatted date string(s) of form:
  1846. X *    Monday 1 August 1988 (Islamic year 1409)
  1847. X * given string labelling date, (Gregorian) year of event, and function which
  1848. X * takes (Gregorian) year as an argument and produces: the (integer) number of
  1849. X * Gregorian dates (1 or 2), the first and second (Julian) days, and the first
  1850. X * and second Islamic years.
  1851. X */
  1852. Xprint_islamic_string(string, year, func)
  1853. X    char    *string;
  1854. X    int    year;
  1855. X    int    (*func) ();
  1856. X{
  1857. X
  1858. X    char    *date;
  1859. X    double    date1, date2, day, holiday;
  1860. X    int    month, myear1, myear2, number_of_dates;
  1861. X    char    *date_string();
  1862. X
  1863. X    holiday = (*func) (
  1864. X        year, &number_of_dates, &date1, &date2, &myear1, &myear2);
  1865. X    if (holiday < 0)
  1866. X        (void) printf("Can not determine requested date\n");
  1867. X    else {
  1868. X        (void) printf("%s (%d) Julian day: %f\n", string, year, date1);
  1869. X        gregorian_date(&day, &month, &year, date1);
  1870. X        date = date_string(get_day_of_week(day, month, year),
  1871. X            day, month, year);
  1872. X        (void) printf("%s (%d): %s", string, year, date);
  1873. X        (void) printf(" (Islamic year %d)\n", myear1);
  1874. X        if (number_of_dates == 2) {
  1875. X            (void) printf(
  1876. X                "%s (%d) Julian day: %f\n", string, year,
  1877. X                date2);
  1878. X            gregorian_date(&day, &month, &year, date2);
  1879. X            date = date_string(get_day_of_week(day, month, year),
  1880. X                day, month, year);
  1881. X            (void) printf("%s (%d): %s", string, year, date);
  1882. X            (void) printf(" (Islamic year %d)\n",
  1883. X                myear2);
  1884. X        }
  1885. X    }
  1886. X}
  1887. X
  1888. X/*
  1889. X * print_date_and_time_string:
  1890. X * Print formatted date/time string of form: 10:42 Thursday 8 December 1988
  1891. X * given string labelling date, year of event, and function which takes year
  1892. X * as an argument and produces Julian day, 
  1893. X */
  1894. Xprint_date_and_time_string(string, year, func)
  1895. X    char    *string;
  1896. X    int    year;
  1897. X    double    (*func)();
  1898. X{
  1899. X    char    *date;
  1900. X    double    btmp, ctmp, day, holiday;
  1901. X    int    atmp, hour, min, month;
  1902. X    char    *date_time_string();
  1903. X
  1904. X    holiday = (*func) (year);
  1905. X    (void) printf("%s (%d) Julian day: %f\n", string, year, holiday);
  1906. X    gregorian_date(&day, &month, &year, holiday);
  1907. X    atmp = day;
  1908. X    btmp = day - atmp;
  1909. X    hour = btmp * 24.0;
  1910. X    ctmp = (btmp - (hour / 24.0)) * 1440.0;
  1911. X    min = ctmp;
  1912. X    date = date_time_string(hour, min, get_day_of_week(day, month, year),
  1913. X        day, month, year);
  1914. X    (void) printf("%s (%d): %s\n", string, year, date);
  1915. X}
  1916. X
  1917. X/*
  1918. X * print_date_string:
  1919. X * Print formatted date string of form: Thursday 8 December 1988
  1920. X * given string labelling date, year of event, and function which takes year
  1921. X * as an argument and produces Julian day. 
  1922. X */
  1923. Xprint_date_string(string, year, func)
  1924. X    char    *string;
  1925. X    int    year;
  1926. X    double    (*func) ();
  1927. X{
  1928. X    char    *date;
  1929. X    double    day, holiday;
  1930. X    int    month;
  1931. X    char    *date_string();
  1932. X
  1933. X    holiday = (*func) (year);
  1934. X    (void) printf("%s (%d) Julian day: %f\n", string, year, holiday);
  1935. X    gregorian_date(&day, &month, &year, holiday);
  1936. X    date = date_string(get_day_of_week(day, month, year), day, month, year);
  1937. X    (void) printf("%s (%d): %s\n", string, year, date);
  1938. X}
  1939. X
  1940. X/*
  1941. X * print_jewish_string:
  1942. X * Print formatted date string of form: Thursday 8 December 1988 (NYEAR)
  1943. X * given string labelling date, year of event, and function which takes year
  1944. X * as an argument, sets the value of a non-Gregorian year (NYEAR), and produces
  1945. X * the Julian day.
  1946. X */
  1947. Xprint_jewish_string(string, year, func)
  1948. X    char    *string;
  1949. X    int    year;
  1950. X    double    (*func) ();
  1951. X{
  1952. X    char    *date;
  1953. X    double    day, holiday;
  1954. X    int    month, nyear;
  1955. X    char    *date_string();
  1956. X
  1957. X    holiday = (*func) (year, &nyear);
  1958. X    (void) printf("%s (%d) Julian day: %f\n", string, year, holiday);
  1959. X    gregorian_date(&day, &month, &year, holiday);
  1960. X    date = date_string_2(get_day_of_week(day, month, year), day, month,
  1961. X        year, nyear);
  1962. X    (void) printf("%s (%d): %s\n", string, year, date);
  1963. X}
  1964. X
  1965. X/*
  1966. X * extract time of day from Julian day
  1967. X */
  1968. Xchar *
  1969. Xjulian_time(jday)
  1970. Xdouble jday;
  1971. X{
  1972. X    double    h1, floor();
  1973. X    int    hours, minutes;
  1974. X
  1975. X    jday += 0.5;  /* Julian day starts at noon GMT */
  1976. X    h1 = (jday - floor(jday)) * 24.; /* number of hours & frac of hours */
  1977. X    hours = (int) floor(h1);
  1978. X    minutes = (int) ((h1 - (double) hours) * 60.);
  1979. X    sprintf(timebuf, " at %d:%02d", hours, minutes);
  1980. X    return(timebuf);
  1981. X}
  1982. X
  1983. X/*
  1984. X * End of code
  1985. X */
  1986. X#endif    /* NO_HOLIDAYS */
  1987. END_OF_FILE
  1988. if test 44896 -ne `wc -c <'datelib.c'`; then
  1989.     echo shar: \"'datelib.c'\" unpacked with wrong size!
  1990. fi
  1991. # end of 'datelib.c'
  1992. fi
  1993. echo shar: End of archive 2 \(of 23\).
  1994. cp /dev/null ark2isdone
  1995. MISSING=""
  1996. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ; do
  1997.     if test ! -f ark${I}isdone ; then
  1998.     MISSING="${MISSING} ${I}"
  1999.     fi
  2000. done
  2001. if test "${MISSING}" = "" ; then
  2002.     echo You have unpacked all 23 archives.
  2003.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2004. else
  2005.     echo You still need to unpack the following archives:
  2006.     echo "        " ${MISSING}
  2007. fi
  2008. ##  End of shell archive.
  2009. exit 0
  2010.  
  2011. exit 0 # Just in case...
  2012. -- 
  2013. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2014. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2015. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2016. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2017.